package ltd.hyangyang.rpc.common.utils;

import ltd.hyangyang.rpc.common.exception.ExceptionEnum;
import ltd.hyangyang.rpc.common.exception.RpcException;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Parameter;
import java.util.concurrent.ConcurrentHashMap;

//构建单例对象
public final class SingletonFactory {

    //使用ConcurrentHashMap，实现单例的效果
    private static ConcurrentHashMap singletonMap = new ConcurrentHashMap();

    public static <T> T getSingletonBean(Class<T> object) {
        if (object == null) {
            throw new RpcException(ExceptionEnum.ARGS_NOT_EMPTY.getMsg());
        }
        String reference = object.toString();
        if (singletonMap.get(reference) != null) {
            return object.cast(singletonMap.get(reference));
        } else {
            //如果在单例map 中没有这个值，则重新创建一个示例
            return object.cast(singletonMap.computeIfAbsent(reference, k -> {
                try {
                    return object.getDeclaredConstructor().newInstance();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }));
        }
    }

    //构造有参构造方法
    public static <T> Constructor<T> getConstructor(Class<T> object, Class<?>... parameterTypes) throws NoSuchMethodException {

        return object.getDeclaredConstructor(parameterTypes);


    }

    public static <T> T checkSingletonExist(Class<T> object) {
        if (object == null) {
            throw new RpcException(ExceptionEnum.ARGS_NOT_EMPTY.getMsg());
        }
        String reference = object.toString();
        Object instance = singletonMap.get(reference);
        if (instance != null) {
            return (T) instance;
        } else {
            return null;
        }
    }

}
